package com.shop.controller;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.shop.constant.UserConstant;
import com.shop.domain.Cart;
import com.shop.domain.Category;
import com.shop.domain.Comment;
import com.shop.domain.Goods;
import com.shop.domain.MessageCenter;
import com.shop.domain.Order;
import com.shop.domain.User;
import com.shop.enumeration.ConditionParam;
import com.shop.enumeration.MessageStatusEnum;
import com.shop.service.CartService;
import com.shop.service.CategoryService;
import com.shop.service.CommentService;
import com.shop.service.GoodsService;
import com.shop.service.MessageCenterService;
import com.shop.service.OrderService;
import com.shop.service.UserService;
import com.shop.util.ComparatorMap;
import com.shop.util.EncodeUtil;
import com.shop.util.SessionUtil;

/**
 * 
 * @author wenjuanhenxing
 * @version V1.0 GoodsController.java 2016-2-28 下午3:49:54
 */
@Controller("goodsController")
@RequestMapping("/goods")
public class GoodsController {

	@Resource(name = "goodsServiceImpl")
	private GoodsService goodsService;

	@Resource(name = "categoryServiceImpl")
	private CategoryService categoryService;

	@Resource(name = "userServiceImpl")
	private UserService userService;

	@Resource(name = "orderServiceImpl")
	private OrderService orderService;

	@Resource(name = "cartServiceImpl")
	private CartService cartService;

	@Resource(name = "commentServiceImpl")
	private CommentService commentService;

	@Resource(name = "messageCenterServiceImpl")
	private MessageCenterService messageCenterService;

	@RequestMapping("/toAddGoods")
	public ModelAndView toAdd() {
		ModelAndView mav = new ModelAndView();
		Map<Long, ArrayList<Category>> smallCategoriesMap = new HashMap<Long, ArrayList<Category>>();
		List<Category> largeCategories = categoryService.getLargeCategory();
		for (Category large : largeCategories) {
			ArrayList<Category> smallCategories = (ArrayList<Category>) categoryService
					.getSubCategory(large.getId());
			smallCategoriesMap.put(large.getId(), smallCategories);
		}
		mav.addObject("largeCategories", largeCategories);
		mav.addObject("smallCategoriesMap", smallCategoriesMap);
		mav.setViewName("addGoods");
		return mav;
	}

	@RequestMapping("/search")
	public ModelAndView search(HttpServletRequest request,
			HttpServletResponse response) {
		List<Goods> goods = null;
		Integer catId = getCategoryIdFromRequest(request);
		String keyword = getKeywordFromRequest(request);
		if (catId != null) {
			goods = goodsService.getGoodsByCategoryId(catId);
		} else if (keyword != null) {
			goods = goodsService.getGoodsByNameLike(keyword);
		} else {
			goods = goodsService.getAllGoods();
		}
		ModelAndView mav = new ModelAndView("search");
		mav.addObject("goodsList", goods);
		request.getSession().setAttribute("goodsList", goods);
		return mav;
	}

	@RequestMapping("/condition")
	public ModelAndView selectBycondition(HttpServletRequest request,
			HttpServletResponse response) {
		@SuppressWarnings("unchecked")
		// ArrayList<Goods> goodsList = (ArrayList<Goods>) request
		// .getAttribute("goodsList"); //无法拿到数据
		ArrayList<Goods> goodsList = (ArrayList<Goods>) request.getSession()
				.getAttribute("goodsList");
		Assert.notEmpty(goodsList);
		String param = request.getParameter("param");
		ConditionParam conditionParam = getParameters(param);
		if (needSort(conditionParam)) {
			Collections.sort(goodsList,
					ComparatorMap.getByCode(conditionParam.getCode()));
		}
		if (needSelect(conditionParam)) {
			goodsList = doSelect(request, conditionParam, goodsList);
		}
		// TODO ajax方案筛选结果
		ModelAndView mav = new ModelAndView("search");
		mav.addObject("goodsList", goodsList);
		request.getSession().setAttribute("goodsList", goodsList);
		return mav;
	}

	private ArrayList<Goods> doSelect(HttpServletRequest request,
			ConditionParam conditionParam, ArrayList<Goods> goodsList) {
		ArrayList<Goods> ret = null;
		String id = conditionParam.getId();
		if (id.equals("03")) {
			ret = doSelectByPriceBetween(request, goodsList);
		} else if (id.equals("05")) {
			ret = doSelectByDegree(conditionParam.getCode(), goodsList);
		} else {
			ret = doSelectByTransactionMode(conditionParam.getCode(), goodsList);
		}
		return ret;
	}

	/**
	 * 根据交易方式(线下|线上)筛选
	 * 
	 * @param code
	 * @param goodsList
	 * @return
	 */
	private ArrayList<Goods> doSelectByTransactionMode(String code,
			ArrayList<Goods> goodsList) {
		if (code.equals("online")) {
			for (int i = 0; i < goodsList.size(); i++) {
				Goods goods = goodsList.get(i);
				if (goods.getTransactionMode() == false) {
					goodsList.remove(i);
				}
			}
		} else { // offline
			for (int i = 0; i < goodsList.size(); i++) {
				Goods goods = goodsList.get(i);
				if (goods.getTransactionMode() == true) {
					goodsList.remove(i);
				}
			}
		}
		return goodsList;
	}

	private ArrayList<Goods> doSelectByPriceBetween(HttpServletRequest request,
			ArrayList<Goods> goodsList) {
		String lowStr = request.getParameter("low");
		String highStr = request.getParameter("high");
		Double low = Double.valueOf(lowStr);
		Double high = Double.valueOf(highStr);
		for (int i = 0; i < goodsList.size(); i++) {
			Goods goods = goodsList.get(i);
			if (!(goods.getPrice().compareTo(low) >= 0 && goods.getPrice()
					.compareTo(high) <= 0)) {
				goodsList.remove(i);
			}
		}
		return goodsList;
	}

	/**
	 * 按成色筛选goods,成色7，8，9以上，6以下
	 * 
	 * @param code
	 * @param goodsList
	 * @return
	 */
	private ArrayList<Goods> doSelectByDegree(String code,
			ArrayList<Goods> goodsList) {
		String degreeStr = code.substring(code.indexOf("_") + 1);
		Double degree = Double.valueOf(degreeStr);
		System.out.println("degree " + degree);
		// 6筛选以下 <=，其他是>=
		if (Math.abs(degree.doubleValue() - 6.0) < 0.000001) {
			for (int i = 0; i < goodsList.size(); i++) {
				Goods goods = goodsList.get(i);
				if (goods.getDegree().compareTo(degree) == 1) {
					goodsList.remove(i);
				}
			}
		} else {
			for (int i = 0; i < goodsList.size(); i++) {
				Goods goods = goodsList.get(i);
				if (goods.getDegree().compareTo(degree) == -1) {
					goodsList.remove(i);
				}
			}
		}
		return goodsList;
	}

	/**
	 * 判断是否需要进行重新排序
	 * 
	 * @param conditionParam
	 * @return
	 */
	private boolean needSort(ConditionParam conditionParam) {
		String id = conditionParam.getId();
		if (id.equals("01") || id.equals("02") || id.equals("04")
				|| id.equals("06")) {
			return true;
		}
		return false;
	}

	/**
	 * 判断是否需要将结果筛选
	 * 
	 * @param conditionParam
	 */
	private boolean needSelect(ConditionParam conditionParam) {
		String id = conditionParam.getId();
		if (id.equals("03") || id.equals("05") || id.equals("07")
				|| id.equals("08")) {
			return true;
		}
		return false;
	}

	private ConditionParam getParameters(String param) {
		// System.out.println("param " + param);
		if (param == null || param.equals("")) {
			return null;
		}
		return ConditionParam.getConditionParamByCode(param);
	}

	@RequestMapping("/detail")
	public ModelAndView toDetail(HttpServletRequest request) {
		String goodsId = request.getParameter("id");
		Long id = Long.valueOf(goodsId);
		Goods goods = goodsService.getGoodsById(id);
		ModelAndView mav = new ModelAndView("goodsDetail");
		mav.addObject("goodsDetail", goods);
		// 放到session?
		// request.getSession().setAttribute("goodsDetail", goods);
		return mav;
	}

	@RequestMapping("/buy")
	public ModelAndView buy(HttpServletRequest request) {
		User curUser = (User) request.getSession().getAttribute("currentUser");
		if (curUser == null) {
			return null;
		}
		String goodsId = request.getParameter("id");
		Long id = Long.valueOf(goodsId);
		Goods goods = goodsService.getGoodsById(id);
		User seller = userService.getUserByName(goods.getSeller());

		// build order
		Order order = new Order();
		order.setGoodsId(goods.getId());
		order.setCount(Long.valueOf(request.getParameter("cnt")));
		order.setPrice(goods.getPrice());
		order.setCreateTime(new Date());
		order.setCustomer(curUser.getId());
		order.setSeller(seller.getId());
		order.setStatus(100);
		orderService.addOrder(order);

		ModelAndView mav = new ModelAndView("checkOrder");
		mav.addObject("goodsDetail", goods);
		mav.addObject("orderDetail", order);
		SessionUtil.setSession(request, "order", order);
		return mav;
	}

	public ModelAndView submitOrder(HttpServletRequest request) {
		User curUser = (User) request.getSession().getAttribute("currentUser");
		if (curUser == null) {
			return null;
		}
		// TODO redirect支付
		return new ModelAndView("cashier");
	}

	public ModelAndView payNext(HttpServletRequest request) {
		// TODO check pay result
		return new ModelAndView("finishOrder");
	}

	// TODO
	private Boolean checkPayResult() {
		return true;
	}

	@RequestMapping("/addCart")
	public void addCart(HttpServletRequest request, HttpServletResponse response) {
		User curUser = (User) request.getSession().getAttribute("currentUser");
		if (curUser == null) {
			return;
		}
		String goodsId = request.getParameter("id");
		Long id = Long.valueOf(goodsId);
		Goods goods = goodsService.getGoodsById(id);

		Cart cart = new Cart();
		String count = request.getParameter("cnt");
		Long cnt = Long.valueOf(count == null ? "0" : count);
		cart.setCount(cnt);
		// TODO 通过读取页面参数减少一次db访问
		cart.setPrice(goods.getPrice() * cnt);
		cart.setGoodsId(id);
		cart.setUserId(curUser.getId());
		cartService.save(cart);

	}

	@RequestMapping("/comment")
	public void addComment(HttpServletRequest request,
			HttpServletResponse response) {
		User curUser = (User) request.getSession().getAttribute("currentUser");
		if (curUser == null) {
			return;
		}
		String goodsId = request.getParameter("id");
		Long id = Long.valueOf(goodsId);
		Goods goods = goodsService.getGoodsById(id);
		User seller = userService.getUserByName(goods.getSeller());

		Comment comment = new Comment();
		comment.setContent(request.getParameter("comment-input"));
		comment.setGoodsId(id);
		comment.setUsername(curUser.getUsername());
		commentService.save(comment);

		sendMessage(UserConstant.COMMENT_NOTIFY, curUser.getId(),
				seller.getId());
	}

	// 发送消息--即消息持久化
	private void sendMessage(String content, Long senderID, Long receiverId) {
		User sender = userService.getUserById(senderID);
		if (sender == null) {
			return;
		}
		if (content.equals(UserConstant.CERTIFY)) {

			content = sender.getUsername() + "申请实名认证";
		}

		MessageCenter message = new MessageCenter();
		message.setReceiver(receiverId);
		message.setSender(senderID);
		message.setStatus(MessageStatusEnum.UNREAD.getKey());
		message.setContent(content);
		messageCenterService.addMessage(message);

	}

	@RequestMapping("/addGoods")
	public ModelAndView addGoods(
			@RequestParam("images") MultipartFile[] images,
			HttpServletRequest request) {
		// 从form中解析参数

		String name = request.getParameter("title");
		Double price = Double.parseDouble(request.getParameter("price"));
		Long stock = Long.parseLong(request.getParameter("stock"));
		Double degree = Double.parseDouble(request.getParameter("degree"));
		String description = request.getParameter("desc");
		Boolean mode = request.getParameter("transactionMode").equals("true");
		Integer largeCategory = Integer.parseInt(request.getParameter("cat"));
		Integer smallCategory = Integer.parseInt(request.getParameter("cat_l"));
		String seller = ((User) (request.getSession()
				.getAttribute("currentUser"))).getUsername();
		String transactionAddress = request.getParameter("trade_place");
		Goods goods = new Goods(name, largeCategory, smallCategory,
				description, price, degree, seller, stock, mode,
				transactionAddress);
		goodsService.addGoods(goods);
		Long id = goods.getId();
		if (images != null && images.length > 0) {
			// 商品key + username
			String prefix = id.toString() + seller;
			downloadImages(prefix, images, request, goods);
		}

		// System.out.println(stock + " desc " + desciption + " mode " + mode
		// + " cat" + category);
		return null;

	}

	private void downloadImages(String prefix, MultipartFile[] images,
			HttpServletRequest request, Goods goods) {
		// 上传路径
		String dir = request.getSession().getServletContext()
				.getRealPath("/goodsImage");
		File dirFile = new File(dir);
		if (!dirFile.exists()) {
			dirFile.mkdir();
		}
		try {
			String imageSrc = "";
			for (int i = 0; i < images.length; i++) {
				MultipartFile img = images[i];
				if (img == null || img.isEmpty() || img.getSize() == 0)
					continue;
				String temp = dir + "/" + prefix + String.valueOf(i) + ".jpg";
				imageSrc += temp;
				if (i < images.length - 1) {
					imageSrc += ";";
				}
				File file = new File(temp);
				img.transferTo(file);
			}
			goods.setImage(imageSrc);
			goodsService.updateImage(goods);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private Integer getCategoryIdFromRequest(HttpServletRequest request) {
		String cat = request.getParameter("category");
		if (cat == null || cat.equals("")) {
			return null;
		}
		return Integer.valueOf(cat);
	}

	private String getKeywordFromRequest(HttpServletRequest request) {
		String key = request.getParameter("keyword");
		if (key == null || key.equals("")) {
			return null;
		}
		try {
			key = EncodeUtil.convert2utf8(key);
		} catch (UnsupportedEncodingException e) {
			System.out.println("conver2utf8 Error");
			e.printStackTrace();
		}
		return key;
	}

	private String getSellerFromRequest(HttpServletRequest request) {
		String seller = request.getParameter("seller");
		if (seller == null || seller.equals("")) {
			return null;
		}
		return seller;
	}
}
